package plp.funcoo.expressions;

import plp.funcoo.environment.compilation.CompilationEnvironment;
import plp.funcoo.environment.compilation.Environment;
import plp.funcoo.environment.execution.ExecutionContext;
import plp.funcoo.environment.execution.ExecutionEnvironment;
import plp.funcoo.exceptions.ClassNotDeclared;
import plp.funcoo.exceptions.MethodAlreadDeclared;
import plp.funcoo.exceptions.MethodNotDeclared;
import plp.funcoo.exceptions.VarAlreadyDeclared;
import plp.funcoo.exceptions.VarNotDeclared;
import plp.funcoo.util.Type;
import plp.funcoo.value.Value;

public class Identifier implements Expression{

	private String idName;
	
	
	public Identifier(String strName) {
		this.idName =  strName;
	}
	
	public boolean equals(Object obj) {
		if (obj instanceof Identifier) {
			return ((Identifier) obj).idName.equals(this.idName);
		}
		return false;
	}
	
	public int hashCode() {
		return idName.hashCode();
	}
	
	
	public String toString() {
		return idName;
	}
	@Override
	public ExecutionEnvironment evaluate(ExecutionEnvironment envi) throws VarNotDeclared, MethodNotDeclared, VarAlreadyDeclared, MethodAlreadDeclared {
	
			((ExecutionContext) envi).setValueAnalyzed( (Value) envi.get(this));
		
		return envi;
	}

	@Override
	public boolean typeCheck(CompilationEnvironment envi)
			throws VarNotDeclared, ClassNotDeclared {
		boolean result = true;
		Type t = envi.get(this); // se estiver no ambiente, entao esta ok.
		return result;
	}

	@Override
	public Type getType(Environment envi) throws VarNotDeclared,
			ClassNotDeclared {
		return  (Type) envi.get(this);
	}
	public String getIdName() {
		return idName;
	}

	public void setIdName(String idName) {
		this.idName = idName;
	}

	@Override
	public Expression makeCopy() {
		return new Identifier(idName);
	}

	
}
